package fun.boomcat.luckyhe.mirai.plugin.dbutils;

import fun.boomcat.luckyhe.mirai.plugin.bean.Reply;
import fun.boomcat.luckyhe.mirai.plugin.command.utils.ReplyMapHandler;
import fun.boomcat.luckyhe.mirai.plugin.mapper.ReplyMapper;
import fun.boomcat.luckyhe.mirai.plugin.utils.MyBatisReplyTableUtil;
import org.apache.ibatis.session.SqlSession;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReplyListModifier {

    public static int insertOneReply(Reply newReply) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        Map<String, Object> replyMap = new HashMap<>();
        replyMap.put("qq", newReply.getQq());
        replyMap.put("type", newReply.getType().getName());
        replyMap.put("keyword", newReply.getKeyword());
        replyMap.put("reply", newReply.getReply());
        replyMap.put("replyState", newReply.getReplyState().getName());

        int res = mapper.insertOneReply(replyMap);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    public static int delOneReply(Reply reply) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        Map<String, Object> replyMap = new HashMap<>();
        replyMap.put("qq", reply.getQq());
        replyMap.put("type", reply.getType().getName());
        replyMap.put("keyword", reply.getKeyword());
        replyMap.put("reply", reply.getReply());

        int res = mapper.delOneReplyByData(replyMap);
        sqlSession.commit();
        sqlSession.close();
        return res;
    }

    public static int getSameReplyCount(Reply reply) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        Map<String, Object> replyMap = new HashMap<>();
        replyMap.put("type", reply.getType().getName());
        replyMap.put("keyword", reply.getKeyword());
        replyMap.put("reply", reply.getReply());

        int res = mapper.hasReplyCount(replyMap);

        sqlSession.close();

        return res;
    }

    public static List<Reply> selectRepliesByQq(long searchQq) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        List<Map<String, Object>> replyMapList = mapper.selectRepliesByQq(searchQq);
        List<Reply> replyList = convertListMapToListReply(replyMapList);

        sqlSession.close();

        return replyList;
    }

    public static int createAutoReplyDB() throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        int res = sqlSession.getMapper(ReplyMapper.class).createAutoReplyDB();
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    public static int createAutoReplyTable() throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        int res = sqlSession.getMapper(ReplyMapper.class).createAutoReplyTable();
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    public static List<Reply> selectAuditingReplies() throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        List<Integer> auditingReplyIds = mapper.selectAuditingReplyIds();
        List<Reply> replyList = new ArrayList<>();

        for (int auditingReplyId : auditingReplyIds) {
            Map<String, Object> map = mapper.selectReplyById(auditingReplyId);
            Reply reply = new Reply();

            reply.setId((Integer) map.get("id"));
            reply.setQq((Long) map.get("qq"));
            reply.setType(ReplyMapHandler.getReplyType((String) map.get("rtype")));
            reply.setKeyword((String) map.get("keyword"));
            reply.setReply((String) map.get("reply"));
            reply.setReplyState(ReplyMapHandler.getReplyState((String) map.get("state")));

            replyList.add(reply);
        }
        sqlSession.close();

        return replyList;
    }

    public static int passReplyById(int id) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        int res = mapper.passReplyById(id);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    public static int delOneReplyById(int id) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        int res = mapper.delOneReplyById(id);
        sqlSession.commit();
        sqlSession.close();

        return res;
    }

    public static List<Reply> selectAllReplies() throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);

        List<Map<String, Object>> maps = mapper.selectAllReplies();
        List<Reply> res = convertListMapToListReply(maps);

        sqlSession.close();

        return res;
    }

    private static List<Reply> convertListMapToListReply(List<Map<String, Object>> maps) {
        List<Reply> res = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            Reply reply = new Reply();
            reply.setId((Integer) map.get("id"));
            reply.setQq((Long) map.get("qq"));
            reply.setType(ReplyMapHandler.getReplyType((String) map.get("rtype")));
            reply.setKeyword((String) map.get("keyword"));
            reply.setReply((String) map.get("reply"));
            reply.setReplyState(ReplyMapHandler.getReplyState((String) map.get("state")));

            res.add(reply);
        }

        return res;
    }

    public static List<Reply> getCompleteMatchReplies(String keyword) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        List<Map<String, Object>> maps = mapper.getCompleteMatchReplies(keyword);
        sqlSession.close();
        return convertListMapToListReply(maps);
    }

    public static List<Reply> getFuzzyMatchReplies(String keyword) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        List<Map<String, Object>> maps = mapper.getFuzzyMatchReplies(keyword);
        sqlSession.close();
        return convertListMapToListReply(maps);
    }

    public static List<Reply> getRegexMatchReplies(String keyword) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        List<Map<String, Object>> maps = mapper.getRegexMatchReplies(keyword);
        sqlSession.close();
        return convertListMapToListReply(maps);
    }

    public static List<Reply> getRegexReplaceMatchReplies(String keyword) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        List<Map<String, Object>> maps = mapper.getRegexReplaceMatchReplies(keyword);
        sqlSession.close();
        return convertListMapToListReply(maps);
    }

    public static Reply selectReplyById(int id) throws IOException {
        SqlSession sqlSession = MyBatisReplyTableUtil.getSqlSession();
        ReplyMapper mapper = sqlSession.getMapper(ReplyMapper.class);
        Map<String, Object> maps = mapper.selectReplyById(id);
        sqlSession.close();

        Reply reply = new Reply();
        reply.setId((Integer) maps.get("id"));
        reply.setQq((Long) maps.get("qq"));
        reply.setType(ReplyMapHandler.getReplyType((String) maps.get("rtype")));
        reply.setKeyword((String) maps.get("keyword"));
        reply.setReply((String) maps.get("reply"));
        reply.setReplyState(ReplyMapHandler.getReplyState((String) maps.get("state")));

        return reply;
    }
}
